#ifndef SYNC_UTILS_H
#define SYNC_UTILS_H

namespace {
    constexpr uint8_t SYNC_AI_CORE = 0x00;
    constexpr uint8_t SYNC_V_V = 0x01;
    constexpr uint8_t SYNC_C_V = 0x02;
};

template<AscendC::HardEvent evt>
class SEvent {
private:
    AscendC::TEventID eventId_{0};
public:
    __aicore__ inline SEvent() {
        eventId_ = GetTPipePtr()->AllocEventID<evt>();
    }

    __aicore__ inline ~SEvent() {
        GetTPipePtr()->ReleaseEventID<evt>(eventId_);
    }

    __aicore__ inline void SetFlag() {
        AscendC::SetFlag<evt>(eventId_);
    }

    __aicore__ inline void WaitFlag() {
        AscendC::WaitFlag<evt>(eventId_);
    }

    __aicore__ inline void operator()() {
        SetFlag();
        WaitFlag();
    }
};

struct SyncNone {
    __aicore__ inline void operator()() {}
    __aicore__ static constexpr void Wait() {}
};


template<uint16_t flag, pipe_t pipe, uint8_t syncMode=SYNC_C_V>
class CrossCoreSync {
public:
    __aicore__ static constexpr void Set() {
        AscendC::CrossCoreSetFlag<syncMode, pipe>(flag);
    }

    __aicore__ static constexpr void Wait() {
        AscendC::CrossCoreWaitFlag(flag);
    }
};

#endif